#if UNITY_EDITOR
using System.Collections;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering.Universal;

namespace FRecorder
{
    /// <summary> 运行时录制 </summary>
    public class RunRecorder : MonoBehaviour
    {
        /// <summary> 目标相机 </summary>
        [HideInInspector] public Camera targetCamera;

        /// <summary> 宽 </summary>
        [HideInInspector] public int width;

        /// <summary> 高 </summary>
        [HideInInspector] public int height;

        /// <summary> 格式 </summary>
        [HideInInspector] public ScreenshotDispose.Format format;

        /// <summary> alpha </summary>
        [HideInInspector] public bool alpha;

        /// <summary> 路径 </summary>
        [HideInInspector] public string path;

        /// <summary> 文件名称 </summary>
        [HideInInspector] public string fileName;

        /// <summary> 帧率 </summary>
        [HideInInspector] public int frameCount;

        /// <summary> 开始帧 </summary>
        [HideInInspector] public int startFrame;

        /// <summary> 结束帧 </summary>
        [HideInInspector] public int endFrame;

        /// <summary> 录制结束回调 </summary>
        public UnityAction OnRecorderEnd;

        /// <summary> 帧递增 </summary>
        int _frameIndex;

        void Start()
        {
            Time.captureFramerate = frameCount;
        }

        void Update()
        {
            if (Time.frameCount <= endFrame)
            {
                var _progress = (float)Time.frameCount / endFrame;
                if (EditorUtility.DisplayCancelableProgressBar("录制输出...", (int)(_progress * 100) + "%", _progress))
                {
                    EditorUtility.ClearProgressBar();
                    OnRecorderEnd?.Invoke();
                    EditorApplication.isPlaying = false;
                }
            }
            else
            {
                EditorUtility.ClearProgressBar();
                OnRecorderEnd?.Invoke();
                EditorApplication.isPlaying = false;
            }

            if (Time.frameCount >= startFrame)
                StartCoroutine(WaitTakeSequenceScreenShot());
        }

        /// <summary> 等待拍摄序列截图 </summary>
        IEnumerator WaitTakeSequenceScreenShot()
        {
            var savePath = $"{path}/{fileName}_{Time.frameCount}";
            ScreenshotDispose.Screenshot(targetCamera, width, height, format, alpha, savePath);
            yield return new WaitForEndOfFrame();
        }
    }

    /// <summary> 截屏处理 </summary>
    public static class ScreenshotDispose
    {
        /// <summary> 录制格式 </summary>
        public enum Format
        {
            PNG,
            JPG
        }

        /// <summary> 环境模式 </summary>
        static CameraClearFlags _cameraClearFlags;

        /// <summary> URP镜头后处理 </summary>
        static bool _renderPostProcessing;

        /// <summary> 背景颜色 </summary>
        static Color _backgroundColor;

        /// <summary> 截屏 </summary>
        public static void Screenshot(Camera targetCamera, int width, int height, Format format, bool alpha, string savePath)
        {
            // targetCamera 目标相机x
            // width        宽
            // height       高
            // format       格式
            // alpha        透明通道
            // savePath     保存路径

            if (!targetCamera)
                return;

            var rt = new RenderTexture(width, height, 24);
            targetCamera.targetTexture = rt;

            var texFormat = alpha ? TextureFormat.ARGB32 : TextureFormat.RGB24;
            var tex = new Texture2D(width, height, texFormat, false);

            targetCamera.Render();
            RenderTexture.active = rt;
            tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            targetCamera.targetTexture = null;
            RenderTexture.active = null;
            byte[] bytes;
            string suffix;
            switch (format)
            {
                case Format.PNG:
                    bytes = tex.EncodeToPNG();
                    suffix = ".png";
                    break;
                case Format.JPG:
                    bytes = tex.EncodeToJPG();
                    suffix = ".jpg";
                    break;
                default:
                    bytes = tex.EncodeToPNG();
                    suffix = ".png";
                    break;
            }

            File.WriteAllBytes($"{savePath}{suffix}", bytes);
        }

        /// <summary> 设置 Alpha 相机环境 </summary>
        public static void SetAlphaEnvironment(Camera cam)
        {
            // cam  相机

            cam.clearFlags = CameraClearFlags.SolidColor;
            cam.backgroundColor = new Color(0, 0, 0, 0);
            var cameraData = cam.GetUniversalAdditionalCameraData();
            if (cameraData)
                cameraData.renderPostProcessing = false;
        }

        /// <summary> 保存相机环境 </summary>
        public static void SaveEnvironment(Camera cam)
        {
            // cam  相机

            _cameraClearFlags = cam.clearFlags;
            _backgroundColor = cam.backgroundColor;

            var cameraData = cam.GetUniversalAdditionalCameraData();
            if (cameraData)
                _renderPostProcessing = cameraData.renderPostProcessing;
        }

        /// <summary> 重置相机环境 </summary>
        public static void ResetEnvironment(Camera cam)
        {
            // cam  相机

            cam.clearFlags = _cameraClearFlags;
            cam.backgroundColor = _backgroundColor;

            var cameraData = cam.GetUniversalAdditionalCameraData();
            if (cameraData)
                cameraData.renderPostProcessing = _renderPostProcessing;
        }
    }
}
#endif